/*
 * SPDX-FileCopyrightText: 2022-2024 Andrew Gunnerson
 * SPDX-License-Identifier: GPL-3.0-only
 */

package com.sanji.audio_test.extension

import android.content.ContentResolver
import android.content.Context
import android.net.Uri
import android.provider.DocumentsContract
import android.telecom.PhoneAccount
import androidx.core.net.toFile
import androidx.documentfile.provider.DocumentFile

/**
 * Android 文档存储的权威机构名称
 * 用于识别 Android 系统的外部存储文档提供者
 */
const val DOCUMENTSUI_AUTHORITY = "com.android.externalstorage.documents"

/**
 * 获取格式化的 URI 字符串表示
 *
 * 根据 URI 的 scheme 提供更友好的显示格式：
 * - 对于文件 URI，直接返回路径
 * - 对于内容 URI，如果是 SAF URI 则尝试显示文档 ID，否则包含权威机构以减少歧义
 * - 对于其他类型的 URI，使用默认的 toString() 方法
 */
val Uri.formattedString: String
    get() = when (scheme) {
        ContentResolver.SCHEME_FILE -> path!!
        ContentResolver.SCHEME_CONTENT -> {
            // 根据权威机构决定是否添加前缀
            val prefix = when (authority) {
                DOCUMENTSUI_AUTHORITY -> ""
                // 当不是 Android 本地文件系统文档提供者提供的 SAF URI 时，包含权威机构以减少歧义
                else -> "[$authority] "
            }
            val segments = pathSegments

            // 如果看起来像 SAF 树/文档 URI，则尝试显示文档 ID
            // 注意：无法实现完全避免误报的方式
            if (segments.size == 4 && segments[0] == "tree" && segments[2] == "document") {
                prefix + segments[3]
            } else if (segments.size == 2 && (segments[0] == "tree" || segments[0] == "document")) {
                prefix + segments[1]
            } else {
                toString()
            }
        }
        else -> toString()
    }

/**
 * 从 URI 中提取电话号码
 *
 * 如果 URI 使用电话协议（tel:），则返回协议特定部分作为电话号码
 * 否则返回 null
 */
val Uri.phoneNumber: String?
    get() = when (scheme) {
        PhoneAccount.SCHEME_TEL -> schemeSpecificPart
        else -> null
    }

/**
 * 将 SAF 树 URI 转换为文档 URI
 *
 * 将存储访问框架（SAF）的树 URI 转换为文档 URI
 * 
 * @throws IllegalArgumentException 如果 URI 不是内容 URI
 * @return 对应的文档 URI
 */
fun Uri.safTreeToDocument(): Uri {
    require(scheme == ContentResolver.SCHEME_CONTENT) { "Not a content URI" }

    val documentId = DocumentsContract.getTreeDocumentId(this)
    return DocumentsContract.buildDocumentUri(authority, documentId)
}

/**
 * 将 URI 转换为 DocumentFile 对象
 *
 * 根据 URI 的 scheme 创建相应的 DocumentFile 实例：
 * - 文件 URI：使用 DocumentFile.fromFile()
 * - 内容 URI：根据路径段结构选择合适的 DocumentFile 创建方法
 *
 * @param context 应用程序上下文
 * @throws IllegalArgumentException 如果 URI 类型不受支持
 * @throws IllegalStateException 如果内容 URI 格式不受支持
 * @return 对应的 DocumentFile 实例
 */
fun Uri.toDocumentFile(context: Context): DocumentFile =
    when (scheme) {
        ContentResolver.SCHEME_FILE -> DocumentFile.fromFile(toFile())
        ContentResolver.SCHEME_CONTENT -> {
            val segments = pathSegments

            // 这些方法仅在 API <21 时可能返回 null
            if (segments.size == 4 && segments[0] == "tree" && segments[2] == "document") {
                DocumentFile.fromSingleUri(context, this)!!
            } else if (segments.size == 2 && segments[0] == "document") {
                DocumentFile.fromSingleUri(context, this)!!
            } else if (segments.size == 2 && segments[0] == "tree") {
                DocumentFile.fromTreeUri(context, this)!!
            } else {
                throw IllegalStateException("Unsupported content URI: $this")
            }
        }
        else -> throw IllegalArgumentException("Unsupported URI: $this")
    }